using namespace std;

#include "Light.h"

Light::Light() : mode(POINT), angle(30), spotExp(0)
{ 
   
   if (_lightNum >= 7) {			
      std::cout << "ERROR: Initializng more than 8 lights. Exiting." << std::endl;
      exit(0);
   }
   
   _lightNum++;
   lightNum = _lightNum + GL_LIGHT0;
   
   amb = Vec3f(0,0,0);
   dif = Vec3f(0,0,0);
   spec = Vec3f(0,0,0);
   pos = Vec3f(0,0,0);
   dir = Vec3f(0,0,0);
}

Light::~Light() 
{ 

}

void Light::draw()
{ 
   GLfloat ambientLight[] = {amb[0], amb[1], amb[2], 1.0f};
   GLfloat diffuseLight[] = {dif[0], dif[1], dif[2], 1.0f};
   GLfloat specular[] = {spec[0], spec[1], spec[2], 1.0f};
   GLfloat lightPos[] = {pos[0], pos[1], pos[2], ((mode == DISTANT) ? 0.0f : 1.0f)};
   GLfloat spotDir[] = {dir[0], dir[1], dir[2]}; 
   
   glEnable(GL_LIGHTING);
   
   glLightfv(lightNum, GL_AMBIENT, ambientLight);
   glLightfv(lightNum, GL_DIFFUSE, diffuseLight);
   glLightfv(lightNum, GL_SPECULAR, specular);
   glLightfv(lightNum, GL_POSITION, lightPos);
   
   if (mode == SPOT) {
      glLightf(lightNum, GL_SPOT_CUTOFF, angle);
      glLightfv(lightNum, GL_SPOT_DIRECTION, spotDir);
      glLightf(lightNum, GL_SPOT_EXPONENT, spotExp);
   }
   
   glEnable(lightNum);
   
   for (unsigned i = 0; i < objects.size(); i++)
   {
      objects[i]->drawShadow(pos, dif, getLightNum());
   }
   
}

void Light::setAmbience(Vec3f value)
{
   amb = value;
}
void Light::setDiffuse(Vec3f value)
{
   dif = value;
}
void Light::setSpecular(Vec3f value)
{
   spec = value;
}
void Light::setPosition(Vec3f value)
{
   pos = value;
}
void Light::setDirection(Vec3f value)
{
   dir = value;
}
void Light::setMode(Mode value)
{
   mode = value;
}
void Light::setSpotAngle(float value)
{
   angle = value;
}
void Light::setSpotExponent(float value)
{
   spotExp = value;
}

Vec3f Light::getPosition()
{
   return pos;
}

void Light::addShadowObject(IDrawable* object)
{
   objects.push_back(object);
}

void Light::enable()
{
   glEnable(lightNum);
}

void Light::disable()
{
   glDisable(lightNum);
}

double Light::getLightNum()
{
   return lightNum - GL_LIGHT0;
}

int Light::_lightNum = -1;


